/**
 *
 */
package de.cbf.cam.dsa.item;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import de.cbf.cam.dsa.item.interfaces.ICompositeEditShapeness;
import de.cbf.cam.dsa.item.model.entities.helper.Shapeness;

/**
 * @author salter
 *
 */
public class ControllerEditShapeness extends AbstractControllerEdit {
	private static final Log logger = LogFactory.getLog(ControllerEditShapeness.class);

	protected Shapeness original;
	protected Shapeness changed;

	protected ICompositeEditShapeness view;

	/**	 */
	public ControllerEditShapeness() {
	}

	@Override
	protected void regardNotification(Integer index) {
		// TODO notification to save should come from ControllerEditItem

	}

	/* (non-Javadoc)
	 * @see de.cbf.cam.dsa.item.AbstractControllerEdit#changePropertyInModel(int)
	 */
	@Override
	protected void changePropertyInModel(int index) {
		//not used as no value in shapeness is directly set by view
	}

	/* (non-Javadoc)
	 * @see de.cbf.cam.dsa.item.AbstractControllerEdit#executeCommand(int, java.lang.Object[])
	 */
	@Override
	protected void executeCommand(int index, Object... parameters) {
		switch (index) {
			case ICompositeEditShapeness.INDEX_SIGNAL_MODIFY_TEXT_LEVEL:
				signalModifyLevelText(parameters);
				break;
			case ICompositeEditShapeness.INDEX_SIGNAL_SELECT_LEVEL:
				signalSelectLevel(parameters);
				break;
			case ICompositeEditShapeness.INDEX_COMMAND_ADD_LEVEL:
				executeAddLevel(parameters);
				break;
			case ICompositeEditShapeness.INDEX_COMMAND_REMOVE_LEVEL:
				executeRemoveLevel(parameters);
				break;
			case ICompositeEditShapeness.INDEX_COMMAND_UP_LEVEL:
				executeUpLevel(parameters);
				break;
			case ICompositeEditShapeness.INDEX_COMMAND_DOWN_LEVEL:
				executeDownLevel(parameters);
				break;
			default:
				break;
		}
	}

	protected void signalModifyLevelText(Object[] parameters) {
		// parameter should be string of newValue
		String text = view.getLevelText();
		if( ! text.isEmpty()){
			view.setActivatedButtonAdd(true);
			//if selection -> edit selection
			String selected = view.getSelectedLevel();
			if(selected == null || selected.isEmpty()){
				//no selection
			}else{
				//edit selected level
				Integer index = changed.getLevelOfDescription(selected);
				changed.setDescriptionAt(index,text);
			}
		}else{
			view.setActivatedButtonAdd(false);
		}
	}

	protected void signalSelectLevel(Object[] parameters) {
		String text = view.getSelectedLevel();
		if( ! text.isEmpty()){
			view.setLevelText(text);
			view.setActivatedButtonAdd(false);
			view.setActivatedButtonRemove(true);
			Integer levelNumber = changed.getLevelOfDescription(text);
			if(levelNumber == 0){
				//it is at the start
				view.setActivatedButtonUp(false);
			}else{
				view.setActivatedButtonUp(true);
			}
			if(levelNumber == changed.getMaxShapenessLevel()-1 ){
				//it is at the end
				view.setActivatedButtonDown(false);
			}else{
				view.setActivatedButtonDown(true);
			}

		}else{
			if(view.getLevelText().isEmpty()){
				view.setActivatedButtonAdd(false);
			}else{
				view.setActivatedButtonAdd(true);
			}
			view.setActivatedButtonUp(false);
			view.setActivatedButtonDown(false);
			view.setActivatedButtonRemove(false);
		}
	}

	protected void executeAddLevel(Object[] parameters) {
		String levelText = view.getLevelText();
		changed.addDescription(levelText);
	}

	protected void executeRemoveLevel(Object[] parameters) {
		String levelText = view.getSelectedLevel();
		if(levelText != null && ! levelText.isEmpty()){
			changed.removeDescription(levelText);
		}
	}

	protected void executeUpLevel(Object[] parameters) {
		String level = view.getSelectedLevel();
		changed.frontDescription(level);
	}

	protected void executeDownLevel(Object[] parameters) {
		String level = view.getSelectedLevel();
		changed.backDescription(level);
	}


	/**
     * set values of changed entity in view
     */
    protected void updateViewData(){
    	//port checks, updating is nonsense if model or view is missing
    	if(view == null){
			return;
		}
		if(changed == null){
			return;
		}
		updateLevels(changed.getShapenessDescriptions());
    }

	protected void updateLevels(Object newValue) {
		if (newValue instanceof List<?>) {
			List<String> levels = new ArrayList<String>();
			List<?> list = (List<?>) newValue;
			for (Object object : list) {
				if (object instanceof String) {
					String level = (String) object;
					levels.add(level);
				}
			}
			view.setShapenessLevels(levels);
		}
	}

	/* (non-Javadoc)
	 * @see de.cbf.cam.dsa.item.AbstractControllerEdit#updatePropertyInView(int, java.lang.Object)
	 */
	@Override
	protected void updatePropertyInView(int index, Object newValue) {
		switch (index) {
		case Shapeness.PI_SHAPENESS_DESCRIPTIONS:
			updateLevels(newValue);
			break;
		default:
			break;
		}

	}

	public ICompositeEditShapeness getView() {
		return view;
	}

	public void setView(ICompositeEditShapeness view) {
		if(this.view != null){
			unRegisterListenersAtView(this.view);
		}
		this.view = view;
		registerListenersAtView(this.view);
	}

	 public Shapeness getShapeness() {
        return changed;
    }

    public void setShapeness(Shapeness shapeness) {
    	try {
			unRegisterModelListeners(this.changed);
			this.original = (Shapeness) shapeness.clone();
			this.changed = shapeness;
			registerModelListeners(this.changed);
		} catch (CloneNotSupportedException e) {
			logger.error("item cloning not possible",e);
		}
		updateViewData();
    }
}
